package arcturus;

//Written by travis Anderson, dont ask me how i did this i just saw the code in my head :-P

import java.util.HashMap;

import java.util.Map.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;
import java.util.Set;

public class HashVectorMap<K, V> extends HashMap<K, V> {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Properties xmap;
	private Properties ymap;
	

	// ====================================
	public HashVectorMap() {
		super();
		this.xmap = new Properties();
		this.ymap = new Properties();

	}

	// ====================================
	public V put(K key, V value) {
		super.put(key, value);
		return value;
	}

	// ====================================
	public V put(K key, V value, int x1, int x2, int y1, int y2) throws Exception {
		if (x1 <= x2 && y1 <= y2) {
			super.put(key, value);
			mapAllX(value, x1, x2);
			mapAllY(value, y1, y2);
		} else {
			throw new Exception(
					"Game Error in Collition Detection\r\nx1 or y1 needs to be less than x2 or y2\r\nValues: x1:"
							+ x1 + " x2:" + x2 + " y1:" + y1 + " y2:" + y2);
		}

		return value;
	}

	// ====================================
	private void mapAllX(V value, int x1, int x2) {
		for (int i = x1; i <= x2; i++) {			
			this.xmap.put(i, value);
		}
	}

	// ====================================
	private void mapAllY(V value, int y1, int y2) {
		for (int i = y1; i <= y2; i++) {
			this.ymap.put(i, value);
		}

	}

	// ====================================

	public V remove(Object key) {
		V rval = this.get(key);		
		super.remove(key);
		this.removeXmappings(rval);
		this.removeYmappings(rval);
		return rval;
	}

	// ====================================
	private void removeXmappings(V val){		
		Set<java.util.Map.Entry<Object, Object>> e = xmap.entrySet();
		V temp;	
	
			List<Entry<Object, Object>> remove = new ArrayList<Entry<Object, Object>>();
			 for(java.util.Map.Entry<Object, Object> ex : e){
				 try{
					 temp = (V)ex.getValue();
						if(temp != null){							 
							 if(val.equals(temp)){						 		
									remove.add(ex);								
							 }
						}
				 }
				 catch(Exception err){
					
					 System.out.println(err.toString());
					 continue; 
				 }
			 };
		if(!remove.isEmpty()){
			e.removeAll(remove);			
		}
		
	}

	// ====================================
	private void removeYmappings(V val) {

		Set<java.util.Map.Entry<Object, Object>> e = ymap.entrySet();
		V temp;		
		List<Entry<Object, Object>> remove = new ArrayList<Entry<Object, Object>>();
		for (java.util.Map.Entry<Object, Object> ex : e) {
			try {
				temp = (V) ex.getValue();
				if(temp != null){
					if (val.equals(temp)) {												
						remove.add(ex);						 
					}
				}
				
			} catch (Exception err) {
				
				System.out.println(err.toString());
				continue;
			}
		};
		if(!remove.isEmpty()){		 	
			e.removeAll(remove);
		}
		
		}
	
	// ====================================
	private void debugoutput(List<Entry<Object, Object>> l){
		
		for(Entry<Object, Object> ex : l){
			System.out.print(ex.getKey()+" ");	
			xmap.remove(Integer.valueOf(ex.getKey().toString()));
		}
		System.out.println();
		
	}
		
	// ====================================
	public boolean isColliding(int x, int y) {
		boolean rval = false;
		boolean xmark = false;
		boolean ymark = false;
		xmark = this.xmap.containsKey(x);		
		ymark = this.ymap.containsKey(y);
		rval = (xmark && ymark);
		return rval;
	}

	// ====================================
	public V getValueAt(int x, int y) {		
		V rval = null;
		if(this.xmap.contains(x)){
			rval = (V) this.xmap.get(x);
		}
		if (rval == null &&  this.ymap.containsKey(y)) {
			rval = (V) this.ymap.get(y);
		}
		return rval;
	}

}
